<xsl:stylesheet version="1.1"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:math="http://exslt.org/math"
	xmlns="http://www.w3.org/2000/svg" 
	extension-element-prefixes="math">

	<xsl:import href="../types-to-classes.xslt" />
	<xsl:include href="../common.xslt" />

	<xsl:param name="default-tree-trunk-length">
		10
	</xsl:param>
	<xsl:param name="default-tree-trunk-girth">
		3
	</xsl:param>
	<xsl:param name="default-depth-divisor">
		2
	</xsl:param>
	<xsl:param name="root-height">1</xsl:param>
	<xsl:param name="leaf-length">5</xsl:param>
	<xsl:param name="leaf-width">1.5</xsl:param>
	
	<xsl:param name="default-leaf-angle-delta">15</xsl:param>

	<xsl:param name="max-branch-angle">
		140
	</xsl:param>
	
	<!-- tree -->	

	<xsl:template match="part[type//@name='tree']" mode="render">
		<xsl:param name="state" select="@state" />

		<g>
			<!--
				TODO use a filter to create the outline, do not do individually
				TODO : this looks crap  filter="url(#outline-filter)"
			-->
			<g>
 				<xsl:apply-templates select="part" mode="render" />
 			</g>
			<!--
				TODO : if you make this transparent it doesn't return an bounding
				box
			-->
			<circle id="grab-point" cx="0" cy="0" r="{$root-height div 4}">
			  <xsl:attribute name="class">
		        <xsl:apply-templates select="type" mode="to-classes">
				  <xsl:with-param name="postfix">-body</xsl:with-param>
				</xsl:apply-templates>
		      </xsl:attribute>			
			</circle>
		</g>

	</xsl:template>

	<xsl:template 
		match="part[type//@name='tree']"
		mode="get-extent">
		<xsl:param name="parent-angle">0</xsl:param>
		<xsl:param name="direction"/>
		<xsl:apply-templates select="part" mode="get-extent">
			<xsl:with-param name="parent-angle" select="$parent-angle"/>
			<xsl:with-param name="direction" select="$direction"/>
		</xsl:apply-templates>
	</xsl:template>

	<!-- tree trunk/branch -->

	<xsl:template 
		match="part[type//@name='tree-trunk' or type//@name='tree-branch']"
		mode="get-extent">
		<xsl:param name="parent-angle">0</xsl:param>
		<xsl:param name="direction"/>
		<xsl:variable name="angle" select="description[@key='angle']/@value + $parent-angle"/>
		<xsl:variable name="length" select="description[@key='length']/@value"/>
		<xsl:variable name="extent">
			<xsl:choose>
				<xsl:when test="$direction='south' and type//@name='tree-trunk'">
					<xsl:value-of select="$root-height"/>
				</xsl:when>
				<xsl:when test="$direction='north' or $direction='south'">
					<xsl:value-of select="-math:sin((90+$angle) * $degrees-to-radians) * $length"/>
				</xsl:when>
				<xsl:when test="$direction='east' or $direction='west'">
					<xsl:value-of select="-math:cos((90+$angle) * $degrees-to-radians) * $length"/>
				</xsl:when>
				<xsl:otherwise>
				<xsl:message><xsl:value-of select="$direction"/></xsl:message>
					<xsl:value-of select="$length"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="child-extent">
			<xsl:apply-templates select="." mode="get-max-child-extent">
				<xsl:with-param name="parent-angle" select="$angle"/>
				<xsl:with-param name="direction" select="$direction"/>
			</xsl:apply-templates>
		</xsl:variable>
		<xsl:value-of select="$extent + $child-extent"/>
	</xsl:template>
	

	
	<xsl:template
		match="part[type//@name='tree-trunk' or type//@name='tree-branch']"
		mode="render">
		<xsl:param name="default-divisor">
			1
		</xsl:param>
		<xsl:param name="default-angle">
			0
		</xsl:param>
		<xsl:param name="position"><xsl:value-of select="position()"/></xsl:param>
		<xsl:param name="last"><xsl:value-of select="last()"/></xsl:param>
	    <xsl:param name="scaley"><xsl:value-of select="1 - ($position - 1) div $last"/></xsl:param>
		<xsl:variable name="angle">
		  <xsl:choose>
  			<xsl:when test="description[@key='angle']">
				<xsl:value-of select="description[@key='angle']/@value" />
			</xsl:when>	  
		    <xsl:otherwise>
		      <xsl:value-of select="$default-angle"/>
		    </xsl:otherwise>
		  </xsl:choose>
		</xsl:variable>

		<xsl:variable name="start-girth">
			<xsl:apply-templates select="." mode="get-girth">
				<xsl:with-param name="default-divisor" select="$default-divisor" />
			</xsl:apply-templates>
		</xsl:variable>

		<xsl:variable name="end-girth">
			<!-- the maximum child girth -->
			<xsl:apply-templates select="." mode="get-max-child-girth">
				<xsl:with-param name="default-divisor"
					select="$default-divisor * $default-depth-divisor" />
			</xsl:apply-templates>
		</xsl:variable>

		<xsl:variable name="length">
			<xsl:choose>
				<xsl:when test="description[@key='length']">
					<xsl:value-of select="description[@key='length']/@value" />
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$default-tree-trunk-length div $default-divisor" />
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>

		<g transform="rotate({$angle})">
		  <g transform="scale(1,{$scaley})">
            <xsl:apply-templates select="." mode="render-branch">
              <xsl:with-param name="start-girth" select="$start-girth"/>
              <xsl:with-param name="end-girth" select="$end-girth"/>
              <xsl:with-param name="length" select="$length"/>
            </xsl:apply-templates>
			<xsl:for-each select="part">
				<xsl:variable name="child-girth">
					<xsl:apply-templates select="." mode="get-girth">
						<xsl:with-param name="default-divisor"
							select="$default-divisor * $default-depth-divisor" />
					</xsl:apply-templates>
				</xsl:variable>
				<xsl:variable name="x-offset">
					<xsl:choose>
						<xsl:when test="$angle > 0">
							<xsl:value-of select="($end-girth - $child-girth) div 2" />
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="($child-girth - $end-girth) div 2" />
						</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>
				<g transform="translate({$x-offset},{-$length})">
				  <g transform="scale(1,{1 div $scaley})">
					<xsl:apply-templates select="." mode="render">
						<xsl:with-param name="default-divisor"
							select="$default-divisor * $default-depth-divisor" />
					    <xsl:with-param name="default-angle" 
					    	select="$max-branch-angle div 2 - ((position()-1) * $max-branch-angle) div last() - $max-branch-angle div (last()*2)" />
					    <xsl:with-param name="position" select="position()"/>
					    <xsl:with-param name="last" select="last()"/>
					</xsl:apply-templates>
			      </g>
				</g>
			</xsl:for-each>
		  </g>
		</g>
	</xsl:template>

	<xsl:template match="part" mode="get-max-child-girth">
		<xsl:param name="index">
			1
		</xsl:param>
		<xsl:param name="count">
			<xsl:value-of select="count(part)" />
		</xsl:param>
		<xsl:param name="max-girth">
			0
		</xsl:param>
		<xsl:param name="default-divisor">
			1
		</xsl:param>
		<xsl:choose>
			<xsl:when test="$count >= $index">
				<xsl:variable name="girth">
					<xsl:apply-templates select="part[$index]"
						mode="get-girth">
						<xsl:with-param name="default-divisor" select="$default-divisor" />
					</xsl:apply-templates>
				</xsl:variable>
				<xsl:variable name="new-max-girth">
					<xsl:choose>
						<xsl:when test="$girth > $max-girth">
							<xsl:value-of select="$girth" />
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="$max-girth" />
						</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>
				<xsl:apply-templates select="."
					mode="get-max-child-girth">
					<xsl:with-param name="index" select="$index + 1" />
					<xsl:with-param name="count" select="$count" />
					<xsl:with-param name="max-girth" select="$new-max-girth" />
					<xsl:with-param name="default-divisor" select="$default-divisor" />
				</xsl:apply-templates>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$max-girth" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template match="part" mode="get-girth">
		<xsl:param name="default-divisor">
			1
		</xsl:param>
		<xsl:choose>
			<xsl:when test="description[@key='girth']">
				<xsl:value-of select="description[@key='girth']/@value" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$default-tree-trunk-girth div $default-divisor" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!--  render branch parts -->
	<xsl:template match="part[type//@name='tree-branch']" mode="render-branch">
		<xsl:param name="start-girth"/>
		<xsl:param name="end-girth"/>
		<xsl:param name="length"/>
		
		<polygon 
			points="{-$start-girth div 2},0 
					{$start-girth div 2},0 
					{$end-girth div 2},{-$length}
					0,{-($length + $end-girth div 2)}
					{-$end-girth div 2},{-$length}
		">
			<xsl:attribute name="class">
	        	<xsl:apply-templates select="type" mode="to-classes">
			  		<xsl:with-param name="postfix">-body</xsl:with-param>
				</xsl:apply-templates>
	        </xsl:attribute>
		</polygon>

	</xsl:template>

	<xsl:template match="part[type//@name='tree-trunk']" mode="render-branch">
		<xsl:param name="start-girth"/>
		<xsl:param name="end-girth"/>
		<xsl:param name="length"/>
		<polygon 
			points="{-$start-girth div 2},{-$length div 2} 
			        {-$start-girth div 1.5},{$root-height} 
			        {-$start-girth div 2.2},0 
			        {-$start-girth div 3},{$root-height} 
			        0,{$root-height div 4} 
					{$start-girth div 3},{$root-height}
					{$start-girth div 2.2},0 			        
					{$start-girth div 1.5},{$root-height} 
					{$start-girth div 2},{-$length div 2} 
					{$end-girth div 2},{-$length}
					0,{-($length + $end-girth div 2)}
					{-$end-girth div 2},{-$length}
		">
			<xsl:attribute name="class">
	        	<xsl:apply-templates select="type" mode="to-classes">
			  		<xsl:with-param name="postfix">-body</xsl:with-param>
				</xsl:apply-templates>
	        </xsl:attribute>
		</polygon>

	</xsl:template>
	
	<!-- foliage -->

	<xsl:template 
		match="part[type//@name='tree-foliage']"
		mode="get-extent">
		<xsl:param name="parent-angle">0</xsl:param>
		<xsl:param name="direction"/>
		<xsl:variable name="extent">
			<xsl:choose>
				<xsl:when test="$direction='north' or $direction='west'">
					<xsl:value-of select="-$leaf-length"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$leaf-length"/>
				</xsl:otherwise>
			</xsl:choose>		
		</xsl:variable>				
		<xsl:value-of select="$extent"/>
	</xsl:template>
	
	<xsl:template
		match="part[type//@name='tree-foliage']"
		mode="render">
      <xsl:apply-templates select="." mode="render-leaf"/>
	</xsl:template>
	
	<xsl:template match="part" mode="render-leaf">
	  <xsl:param name="quantity"><xsl:value-of select="round(description[@key='density']/@value)"/></xsl:param>
	  <xsl:param name="position">1</xsl:param>
	  <xsl:param name="angle-delta"><xsl:value-of select="$default-leaf-angle-delta"/></xsl:param>
	  <xsl:param name="angle"><xsl:value-of select="-($quantity - 1) * $angle-delta div 2"/></xsl:param>
      <xsl:if test="$quantity >= $position">
        <g transform="rotate({$angle})">
          <xsl:apply-templates select="." mode="render-leaf-body"/>
        </g>
        <xsl:apply-templates select="." mode="render-leaf">
          <xsl:with-param name="qantity" select="$quantity"/>
          <xsl:with-param name="position" select="$position+1"/>
          <xsl:with-param name="angle-delta" select="$angle-delta"/>
          <xsl:with-param name="angle" select="$angle + $angle-delta"/>
        </xsl:apply-templates>
      </xsl:if>
	</xsl:template>
	
	<xsl:template match="part" mode="render-leaf-body">
	  <polygon points="0,0 {$leaf-width div 2},{-$leaf-length div 2} 0,{-$leaf-length} {-$leaf-width div 2},-{$leaf-length div 2}">
		  <xsl:attribute name="class">
	        <xsl:apply-templates select="type" mode="to-classes">
			  <xsl:with-param name="postfix">-body</xsl:with-param>
			</xsl:apply-templates>
	      </xsl:attribute>
	  </polygon>
	</xsl:template>
</xsl:stylesheet>